#pragma once

#include <system_error>

namespace helper {
namespace sqlite {
namespace error  {

enum sqlite_error {
  ok          =  0   ,//SQLITE_OK            /* OK */
  error       =  1   ,//SQLITE_ERROR         /* Generic error */
  internal    =  2   ,//SQLITE_INTERNAL      /* Internal logic error in SQLite */
  perm        =  3   ,//SQLITE_PERM          /* Access permission denied */
  abort       =  4   ,//SQLITE_ABORT         /* Callback routine requested an abort */
  busy        =  5   ,//SQLITE_BUSY          /* The database file is locked */
  locked      =  6   ,//SQLITE_LOCKED        /* A table in the database is locked */
  nomem       =  7   ,//SQLITE_NOMEM         /* A malloc() failed */
  readonly    =  8   ,//SQLITE_READONLY      /* Attempt to write a readonly database */
  interrupt   =  9   ,//SQLITE_INTERRUPT     /* Operation terminated by sqlite3_interrupt()*/
  ioerr       = 10   ,//SQLITE_IOERR         /* Some kind of disk I/O error occurred */
  corrupt     = 11   ,//SQLITE_CORRUPT       /* The database disk image is malformed */
  notfound    = 12   ,//SQLITE_NOTFOUND      /* Unknown opcode in sqlite3_file_control() */
  full        = 13   ,//SQLITE_FULL          /* Insertion failed because database is full */
  cantopen    = 14   ,//SQLITE_CANTOPEN      /* Unable to open the database file */
  protocol    = 15   ,//SQLITE_PROTOCOL      /* Database lock protocol error */
  empty       = 16   ,//SQLITE_EMPTY         /* Internal use only */
  schema      = 17   ,//SQLITE_SCHEMA        /* The database schema changed */
  toobig      = 18   ,//SQLITE_TOOBIG        /* String or BLOB exceeds size limit */
  constraint  = 19   ,//SQLITE_CONSTRAINT    /* Abort due to constraint violation */
  mismatch    = 20   ,//SQLITE_MISMATCH      /* Data type mismatch */
  misuse      = 21   ,//SQLITE_MISUSE        /* Library used incorrectly */
  nolfs       = 22   ,//SQLITE_NOLFS         /* Uses OS features not supported on host */
  auth        = 23   ,//SQLITE_AUTH          /* Authorization denied */
  format      = 24   ,//SQLITE_FORMAT        /* Not used */
  range       = 25   ,//SQLITE_RANGE         /* 2nd parameter to sqlite3_bind out of range */
  notadb      = 26   ,//SQLITE_NOTADB        /* File opened that is not a database file */
  notice      = 27   ,//SQLITE_NOTICE        /* Notifications from sqlite3_log() */
  warning     = 28   ,//SQLITE_WARNING       /* Warnings from sqlite3_log() */
  row         = 100  ,//SQLITE_ROW           /* sqlite3_step() has another row ready */
  done        = 101  ,//SQLITE_DONE          /* sqlite3_step() has finished executing */
};

class SqliteErrorCategory : public std::error_category {
public:
  const char * name() const noexcept override;
  std::string message(int ev) const override;
  std::error_condition default_error_condition(int ev) const noexcept override ;
};


inline std::error_category const & SqliteCategory() noexcept{
  static const SqliteErrorCategory instance;
  return instance;
}

inline std::error_code make_error_code(sqlite_error e) noexcept{
  return e != sqlite_error::ok ? std::error_code(static_cast<int>(e), SqliteCategory()) : std::error_code();
}

inline std::error_condition make_error_conditon(sqlite_error e) noexcept{
  return std::error_condition(static_cast<int>(e), SqliteCategory());
}
  
}//namespace error
}//namespace sqlite
}//namespace helper

namespace std {
  template<> 
  struct is_error_code_enum<helper::sqlite::error::sqlite_error> : public true_type{};
}//namespace std

namespace helper {
namespace sqlite {
namespace error {
  void ShowErrorMsg(const char * func, const int line, std::error_code & err);
}//namespace error
}//namespace sqlite 
}//namespace helper 
